/* Schema dependencies */

var Gene = require('../schema/GeneSchema').GeneSchema,
    Disease = require('../schema/DiseaseSchema').DiseaseSchema;

/**
 * Finds all Genes that satisfy the given parameters.
 * See API documentation: GET /genes/
 *
 * @param req  {HTTP Request}  : HTTP GET request passed from the route
 * @param res  {HTTP Response} : Waiting HTTP response passed from the route
 *
 * @response {JSON Object}     : JSON array of Gene objects
 **/

exports.index = function(req, res) {
    var query = Gene.find().exclude('_id', 'links.diseases._id');
    
    // Limit by range
    if (req.query.range) {
        query.limit(req.query.range);
    }

    // Use regular expressions to do a "starts with" filter
    if (req.query.contains) {
        var regexFilter = new RegExp('.*' + req.query.contains + ".*");
        query.regex('name', regexFilter);
    }
    
    // Limit by family
    if (req.query.family) {
        query.where('family').equals(req.query.family);
    }
    
    // Limit by area
    if (req.query.area) {
        query.where('links.disease.area').equals(req.query.area);
    }
    query.exec(function(err, gene) {
        // TODO: JSON error messages
        if (err) {
            console.log(err);
        } else {
            res.json(gene);
        } 
    });
};

/**
 * Creates a Gene object using the parameters found in the request body.
 * See API documentation: POST /genes/
 *
 * @param req  {HTTP Request}  : HTTP POST request passed from the route
 * @param res  {HTTP Response} : Waiting HTTP response passed from the route
 *
 * @response {JSON Object}     : JSON object representing success or error
 **/

exports.create = function(req, res) {

    // Create the Model
    var newGene = new Gene(
        {
            id         : req.body.id, // Entrez ID
            symbol: req.body.symbol,
            name  : req.body.name,
            family     : req.body.family,
            links      : {
                diseases : []
            }
        }
    );
    
    // Save the Model in the database
    newGene.save(function(err) {
        // TODO: JSON error messages
        if (err) { console.log(err); }
        var returnBody = {
            success : true,
            id      : newGene.id,
            code    : 100,
            message : "Gene successfully added to the database."
        };
        res.json(returnBody);
    });
};

/**
 * Finds a single Gene object with the given gene ID.
 * See API documentation: GET /genes/[id]
 *
 * @param req  {HTTP Request}  : HTTP GET request passed from the route
 * @param res  {HTTP Response} : Waiting HTTP response passed from the route
 *
 * @response {JSON Object}     : JSON representation of desired Gene object
 **/

exports.show = function(req, res) {
    var query = Gene.findOne()
        .where('id').equals(req.params.gene)
        .exclude('_id', 'links.diseases._id');
    query.exec(function(err, gene) {
        // TODO: JSON error messages
        if (err) { 
            console.log(err);
        } else if (gene === null) {
            var nullGene = {
                success: false,
                code: 101,
                message: "Gene #" + req.params.gene + " not found in database."
            };
            res.json(nullGene, 404);
        } else { 
            res.json(gene);
        }
    });
};

/**
 * Updates a single Gene object with the given gene ID.
 * Accepts partial representations of the Gene object.
 * See API documentation: PUT /genes/[id]
 *
 * @param req  {HTTP Request}  : HTTP PUT request passed from the route
 * @param res  {HTTP Response} : Waiting HTTP response passed from the route
 *
 * @response {JSON Object}     : JSON object representing success or error.
 **/

exports.update = function(req, res) {
    var updatedDoc = {};

    if (req.body.symbol) { 
        updatedDoc.symbol = req.body.symbol;
    }
    if (req.body.name) { 
        updatedDoc.name = req.body.name; 
    }
    if (req.body.family) { 
        updatedDoc.family = req.body.family; 
    }
    if (req.body.disease) {
        Disease.findOne({id: req.body.disease}, function(err, disease) {
            disease.links.gene.push(req.params.gene);
            disease.save(function(err) {
                if (err) {
                    console.log(err);
                } else {
                    Gene.findOne({id: req.params.gene}, function(err, gene) {
                        gene.links.diseases.push(req.body.disease);
                        gene.save(function(err) {
                            if (err) {
                                console.log(err);
                            }
                        });
                    });
                }
            });
        });
    }

    Gene.update({id: req.params.gene}, updatedDoc, function(err) {
        if (err) {
            // TODO: JSON error messages
            console.log(err);
        } else {
            var returnBody = {
                success : true,
                code    : 200,
                message : "Gene successfully updated in the database."
            };
            res.json(returnBody);
        }
    });
};

/**
 * Deletes a single Gene object with the given gene ID.
 * See API documentation: DELETE /genes/[id]
 *
 * @param req  {HTTP Request}  : HTTP DELETE request passed from the route
 * @param res  {HTTP Response} : Waiting HTTP response passed from the route
 *
 * @response {JSON Object}     : JSON object representing success or error.
 **/

exports.destroy = function(req, res) {
    Gene.remove({id: req.params.gene}, function(err) {
        if (err) { 
            // TODO: JSON error messages
            console.log(err);
        } else {
            var returnBody = {
                success : true,
                code    : 300,
                message : "Gene successfully deleted from the database."
            };
            res.json(returnBody);
        }
    });
};
